home *** CD-ROM | disk | FTP | other *** search
- /*
- HASScripting.c from Hsoi's App Shell ©1995-1997 John C. Daub. All rights reserved.
-
- Minimal Scripting Support:
- service "get data" and "set data" events
- in which the object descriptor is "contents of selection"
-
- This file (as is) is taken from WEDemoScripting.c from the WASTE Demo App written
- by Marco Piovanelli. Slight modifications have been made for the code to work (and
- be consistent with) Hsoi's App Shell.
-
- Based on public domain code written by:
- Ed Lai, Apple Computer Inc.
-
- Copyright © 1993-1995 Marco Piovanelli
- All Rights Reserved
-
- */
-
-
- /* How to use this and/or test things:
-
- With this basic and minimal scripting support that HAS has, here's how you
- can see it in action.
-
- First, you must have some way of implimenting the script, such as Apple's
- Script Editor.
-
- Launch the Script Editor and in the editing window, type something like
- this:
-
- [to try get data]
-
- get the contents of selection of application "Hsoi's App Shell Demo 68k"
-
- [to try set data]
-
- set the contents of selection of application "Hsoi's App Shell Demo 68k" to "fred"
-
- (you can substitute the name of your application in place of Hsoi's App Shell Demo 68k,
- but whatever you do, make sure it's the exact name of the application)
-
- then, launch the HAS Demo. Type something, select it (or part of it). Switch back
- to the Script Editor (and you might want to position windows on your monitor
- so that you can see both the Script Editor result window and the HAS window with
- your selection) and run the script. You should see things work just peachy.
-
-
- */
-
- #pragma mark ••• #includes •••
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #ifndef __AEREGISTRY__
- #include <AERegistry.h>
- #endif
-
- #ifndef _WASTE_
- #include "WASTE.h"
- #endif
- #include "HASGlobals.h"
- #ifndef __HSOIS_APP_SHELL__
- #include "HASMain.h"
- #endif
- #include "HASScripting.h"
- #include "HASUtilities.h"
-
- #pragma mark -
- #pragma mark ••• Utils •••
-
- // initialize a descriptor
-
- static void HsoiInitDesc(AEDesc *desc)
- {
- desc->descriptorType = typeNull;
- desc->dataHandle = NULL;
-
- return;
- }
-
- static Boolean HsoiPropertyOf(const AERecord *spec, short *propLevel, PropArray properties)
- {
- AERecord objSpec;
- AEKeyword key;
- DescType theType;
- DescType actualType;
- Size actualSize;
- Boolean retVal = false;
-
- HsoiInitDesc(&objSpec);
-
- // if spec is an Apple event (*propLevel = 0), extract its direct parameter
- // otherwise spec is an object specifier record: extract its container param
- key = (*propLevel == 0) ? keyDirectObject : keyAEContainer;
-
- // extract object specifier
- if (AEGetParamDesc(spec, key, typeAERecord, &objSpec) != noErr)
- goto cleanup;
-
- // does this object specifier specify a property?
- if (AEGetParamPtr(&objSpec, keyAEDesiredClass, typeType, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
-
- // sanity check: make sure the key form is formPropertyID
- // this is probably redundant, but checking doesn't hurt
- if (AEGetParamPtr(&objSpec, keyAEKeyForm, typeEnumerated, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
- if (theType != formPropertyID)
- goto cleanup;
-
- // which property does this object specifier specify?
- if (AEGetParamPtr(&objSpec, keyAEKeyData, typeType, &actualType,
- &theType, sizeof(theType), &actualSize) != noErr)
- goto cleanup;
-
- // bump property level and save property tag into property array
- properties[(*propLevel)++] = theType;
-
- // property of what?
- if (AESizeOfParam(&objSpec, keyAEContainer, &actualType, &actualSize) == noErr)
- if (actualType == typeNull)
- // property of application (i.e., null container): we are done
- retVal = true;
- else if ((actualType == typeObjectSpecifier) && (*propLevel < kMaxPropLevel))
- // property of another object, so do a recursive call
- // unless we have already reached max recursion depth
- retVal = HsoiPropertyOf(&objSpec, propLevel, properties);
-
- cleanup:
- AEDisposeDesc(&objSpec);
- return retVal;
- }
-
- #pragma mark -
- #pragma mark ••• Event Handler Utils •••
-
- OSErr HsoiWEGetContentsDesc(long rangeStart, long rangeEnd, Boolean wantStyledText,
- AEDesc *desc, WEReference we)
- {
- AEDesc textDesc, stylesDesc, recordDesc;
- OSErr err;
-
- HsoiInitDesc(desc);
- HsoiInitDesc(&textDesc);
- HsoiInitDesc(&stylesDesc);
- HsoiInitDesc(&recordDesc);
-
- // allocate a handle to hold the text
- textDesc.dataHandle = NewHandle(0);
- textDesc.descriptorType = typeChar;
- if ((err = MemError()) != noErr)
- goto cleanup;
-
- if (wantStyledText)
- {
- // allocate a handle to hold the styles
- stylesDesc.dataHandle = NewHandle(0);
- stylesDesc.descriptorType = typeScrapStyles;
- if ((err = MemError()) != noErr)
- goto cleanup;
- } // if wantStyledText
-
- // make a copy of the specified text range
- if ((err = WECopyRange(rangeStart, rangeEnd, textDesc.dataHandle,
- (StScrpHandle) stylesDesc.dataHandle, NULL, we)) != noErr)
- goto cleanup;
-
- if (wantStyledText)
- {
- // create an Apple event record to hold text + styles
- if ((err = AECreateList(NULL, 0, true, &recordDesc)) != noErr)
- goto cleanup;
-
- // add the text descriptor to the record
- if ((err = AEPutParamDesc(&recordDesc, keyAEText, &textDesc)) != noErr)
- goto cleanup;
- AEDisposeDesc(&textDesc);
-
- // add the styles descriptor to the record
- if ((err = AEPutParamDesc(&recordDesc, keyAEStyles, &stylesDesc)) != noErr)
- goto cleanup;
- AEDisposeDesc(&stylesDesc);
-
- // coerce the record into a styled text descriptor
- if ((err = AECoerceDesc(&recordDesc, typeStyledText, desc)) != noErr)
- goto cleanup;
-
- }
- else {
- *desc = textDesc;
- HsoiInitDesc(&textDesc);
- }
-
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&stylesDesc);
- AEDisposeDesc(&recordDesc);
-
- return err;
- }
-
- OSErr HsoiWESetContentsDesc(long rangeStart, long rangeEnd,
- const AEDesc *desc, WEReference we)
- {
- AEDesc textDesc, stylesDesc, recordDesc;
- OSErr err;
-
- HsoiInitDesc(&textDesc);
- HsoiInitDesc(&stylesDesc);
- HsoiInitDesc(&recordDesc);
-
- // we expect desc type to be either TEXT or STXT
- if (desc->descriptorType == typeStyledText)
- {
- // STYLED TEXT
- // coerce the styled text descriptor to an Apple event record
- if ((err = AECoerceDesc(desc, typeAERecord, &recordDesc)) != noErr)
- goto cleanup;
-
- // extract text + styles from the record
- if ((err = AEGetParamDesc(&recordDesc, keyAEText, typeChar, &textDesc)) != noErr)
- goto cleanup;
- if ((err = AEGetParamDesc(&recordDesc, keyAEStyles, typeScrapStyles, &stylesDesc)) != noErr)
- goto cleanup;
- }
- else {
- // UNSTYLED TEXT
- if ((err = AECoerceDesc(desc, typeChar, &textDesc)) != noErr)
- goto cleanup;
- }
-
- // replace the specified range with the given text
- HLock(textDesc.dataHandle);
- WESetSelection(rangeStart, rangeEnd, we);
- err = WEInsert(*textDesc.dataHandle, GetHandleSize(textDesc.dataHandle),
- (StScrpHandle) stylesDesc.dataHandle, NULL, we);
- HUnlock(textDesc.dataHandle);
-
- cleanup:
- AEDisposeDesc(&recordDesc);
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&stylesDesc);
-
- return err;
- }
-
- #pragma mark -
- #pragma mark ••• Event Handlers •••
-
- static pascal OSErr HsoiHandleGetData(const AppleEvent *ae, AppleEvent *reply, long refCon)
- {
- #pragma unused (refCon)
-
- AEDesc textDesc;
- DocumentHandle hDocument;
- short propLevel = 0;
- PropArray properties;
- FlavorType requestedType;
- Boolean wantStyledText = false;
- DescType actualType;
- Size actualSize;
- long selStart, selEnd;
- OSErr err;
-
- HsoiInitDesc(&textDesc);
-
- // the only Apple event object we recognize is "contents of selection"
- err = errAENoSuchObject;
- if (!HsoiPropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
- (properties[0] != pContents) || (properties[1] != pSelection))
- {
- goto cleanup;
- }
-
- // extract the optional parameter keyAERequestedType, if present
- // The Apple Event Registry says this parameter can be a list
- // of type tags, but in most cases it is just a single tag, as we assume here.
- if (AEGetParamPtr(ae, keyAERequestedType, typeType, &actualType,
- &requestedType, sizeof(requestedType), &actualSize) == noErr)
- {
- wantStyledText = (requestedType == typeStyledText);
- }
-
- // make sure there is a document window in front
- err = errAENoUserSelection;
- if ((hDocument = HsoiGetWindowDocument(FrontWindow())) == NULL)
- {
- goto cleanup;
- }
-
- // get the selection range
- WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
-
- // create an Apple event descriptor for the selected text
- if ((err = HsoiWEGetContentsDesc(selStart, selEnd, wantStyledText,
- &textDesc, (*hDocument)->we)) != noErr)
- {
- goto cleanup;
- }
-
- // put the text descriptor into the reply event
- if ((err = AEPutParamDesc(reply, keyDirectObject, &textDesc)) != noErr)
- {
- goto cleanup;
- }
-
- // clear result code
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
-
- return err;
- }
-
- static pascal OSErr HsoiHandleSetData(const AppleEvent *ae, AppleEvent *reply, long refCon)
- {
- #pragma unused (reply, refCon)
-
- AEDesc textDesc;
- DocumentHandle hDocument;
- short propLevel = 0;
- PropArray properties;
- long selStart, selEnd;
- OSErr err;
-
- HsoiInitDesc(&textDesc);
-
- // the only Apple event object we recognize is "contents of selection"
- err = errAENoSuchObject;
- if (!HsoiPropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
- (properties[0] != pContents) || (properties[1] != pSelection))
- {
- goto cleanup;
- }
-
- // make sure there is a document window in front
- err = errAENoUserSelection;
- if ((hDocument = HsoiGetWindowDocument(FrontWindow())) == NULL)
- {
- goto cleanup;
- }
-
- // extract the required keyAEData parameter
- if ((err = AEGetParamDesc(ae, keyAEData, typeWildCard, &textDesc)) != noErr)
- goto cleanup;
-
- // get current selection range
- WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
-
- // set the contents of the selection
- if ((err = HsoiWESetContentsDesc(selStart, selEnd, &textDesc, (*hDocument)->we)) != noErr)
- {
- goto cleanup;
- }
-
- // clear result code
- err = noErr;
-
- cleanup:
- AEDisposeDesc(&textDesc);
-
- return err;
- }
-
- #pragma mark -
- #pragma mark ••• Install Handlers •••
-
- // the apple event installed...called in HsoiDoAEInstallation()
-
- OSErr HsoiInstallCoreHandlers(void)
- {
- OSErr err;
-
- if ((err = AEInstallEventHandler(kAECoreSuite, kAEGetData,
- NewAEEventHandlerProc(HsoiHandleGetData), 0L, false)) != noErr)
- {
- return err;
- }
-
- if ((err = AEInstallEventHandler(kAECoreSuite, kAESetData,
- NewAEEventHandlerProc(HsoiHandleSetData), 0L, false)) != noErr)
- {
- return err;
- }
-
- return noErr;
- }